/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = frcmd_parse_detail.c                               */
/*  NOTE      =                                                    */
/*  DATE      = 2014/12/03 by guojq                                */
/*******************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>

#include "frcomm.h"
#include "frmem.h"
#include "frsutl.h"
#include "frcmd_parse.h"
#include "frcmd_client.h"
#include "client.pb-c.h"

/*******************************************************************************
*  FUNC     :  把filter命令数据转换成protobuf-c类型的数据
*  ARGS     :  p_st_cmd         命令的格式
*           :  pp_data          转换成功的数据
*           :  p_ui_out         转换成功的数据长度
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :  pp_data需要外面释放
*******************************************************************************/
FR_STATIC int __protobuf_do_pack(Command *p_st_cmd, char **pp_data, unsigned int *p_ui_out)
{
    unsigned int ui_len = 0;
    void *p_out = NULL;
    
    if (p_st_cmd == NULL)
        return FR_FAIL;
    
    ui_len = command__get_packed_size(p_st_cmd);
    p_out = frmalloc(ui_len);
    if (p_out == NULL)
        return FR_FAIL;
    
    command__pack(p_st_cmd, p_out);
    *p_ui_out = ui_len;
    *pp_data = p_out;
    
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  初始化protobuf格式的数据
*  ARGS     :  p_st_command         最后的结构体
*           :  pp_st_filter_cmd     出力的FilterCommand
*           :  pp_filter            出力的filter
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :  pp_st_filter_cmd，pp_filter需要外面释放
*******************************************************************************/
FR_STATIC int __filter_init(Command *p_st_command, FilterCommand **pp_st_filter_cmd, Filter **pp_filter)
{
    FilterCommand *p_st_filter_cmd_tmp = NULL;
    Filter *p_filter_tmp_out = NULL;
    
    p_st_filter_cmd_tmp = frmalloc(sizeof(FilterCommand));
    if (p_st_filter_cmd_tmp == NULL)
        return FR_FAIL;
    
    p_filter_tmp_out = frmalloc(sizeof(Filter));
    if (p_filter_tmp_out == NULL)
    {
        frfree(p_st_filter_cmd_tmp);
        return FR_FAIL;
    }
    memset(p_st_filter_cmd_tmp, 0x00, sizeof(FilterCommand));
    memset(p_filter_tmp_out, 0x00, sizeof(Filter));
    
    filter_command__init(p_st_filter_cmd_tmp);
    filter__init(p_filter_tmp_out);
    
    p_st_command->cmd_type = COMMAND__COMMAND_TYPE__Type_FilterCommand;
    p_st_command->filter_cmd = p_st_filter_cmd_tmp;
    
    *pp_st_filter_cmd = p_st_filter_cmd_tmp;
    *pp_filter = p_filter_tmp_out;
    
    return FR_SUCC;
    
}

/*******************************************************************************
*  FUNC     :  分隔ip地址段和端口段
*  ARGS     :  p_iprange            ip地址段
*           :  pp_portrange         出力的地址段
*  RTN      :
*  NOTE     :  出力的都只是指针，破坏传进来的数据(\0结尾)
*******************************************************************************/
void __split_iprange_portrange(char *p_iprange, char **pp_portrange)
{
    char *p_tmp = NULL;
    
    if (p_iprange)
    {
        p_tmp = strchr(p_iprange, '|');
        if (p_tmp)
        {
            *p_tmp = '\0';
            *pp_portrange = p_tmp + 1;
        }
    }
}

/*******************************************************************************
*  FUNC     :  添加/删除filter规则 的命令
*              setup filter cmd [mac] [ip_proto] [ip-range] [port-range] [ip-range] [port-range]
*  ARGS     :  p_action             添加/删除
*           :  p_ip_proto           协议字符串
*           :  p_src_iprange_portrange   源ip地址段和端口段
*           :  p_dst_iprange_portrange   目的ip地址段和端口段
*           :  p_mac                mac地址
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
int frcmd_filter(char *p_action, char* p_ip_proto, char *p_src_iprange_portrange, char *p_dst_iprange_portrange, char *p_mac)
{
    Command st_command;
    char *p_packed = NULL;
    unsigned int ui_pack_len = 0;
    FilterCommand *p_st_filter_cmd = NULL;
    Filter *p_filter_tmp = NULL;
    Filter **p_filter;
    char *p_src_iprange = p_src_iprange_portrange;
    char *p_src_portrange = NULL;
    char *p_dst_iprange = p_dst_iprange_portrange;
    char *p_dst_portrange = NULL;
    
    //printf("frcmd_filter start p_action=[%s],p_ip_proto=[%s],range=[%s],drange=[%s],mac=[%s]\n", p_action, p_ip_proto,p_src_iprange_portrange,p_dst_iprange_portrange, p_mac);
    
    command__init(&st_command);
    
    //初始化filter信息
    if (__filter_init(&st_command, &p_st_filter_cmd, &p_filter_tmp) != FR_SUCC)
        return FR_FAIL;
        
    p_filter = frmalloc(sizeof(Filter *));
    if (p_filter == NULL)
        goto err;
    
    __split_iprange_portrange(p_src_iprange, &p_src_portrange);
    __split_iprange_portrange(p_dst_iprange, &p_dst_portrange);
    
    p_st_filter_cmd->action = p_action;
    if (p_ip_proto)
        p_filter_tmp->ip_proto = FR_L4STR2PROTO(p_ip_proto);
    else
        p_filter_tmp->ip_proto = 0;
    p_filter_tmp->ip_from = p_src_iprange;
    p_filter_tmp->ip_to = p_dst_iprange;
    p_filter_tmp->port_from = p_src_portrange;
    p_filter_tmp->port_to = p_dst_portrange;
    p_filter_tmp->mac = p_mac;
    p_filter[0] = p_filter_tmp;
    p_st_filter_cmd->filters = p_filter;
    //todo
    p_st_filter_cmd->n_filters = 1;
    
    //通过protobuf转化成字符串
    if (__protobuf_do_pack(&st_command, &p_packed, &ui_pack_len) != FR_SUCC)
        goto err;
    
    //和服务端通信，并接收服务端返回的信息
    if (frcmd_talking(p_packed, ui_pack_len) != FR_SUCC)
        goto err;
    
    if (p_filter_tmp)
        frfree(p_filter_tmp);
    if (p_filter)
        frfree(p_filter);
    if (p_st_filter_cmd)
        frfree(p_st_filter_cmd);
    if (p_packed)
        frfree(p_packed);
    
    return FR_SUCC;
err:
    if (p_filter_tmp)
        frfree(p_filter_tmp);
    if (p_filter)
        frfree(p_filter);
    if (p_st_filter_cmd)
        frfree(p_st_filter_cmd);
    if (p_packed)
        frfree(p_packed);
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  清空filter规则 的命令
*              -c “setup filter clear”
*  ARGS     :
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
int frcmd_filter_clear(void)
{
    Command st_command;
    char *p_packed = NULL;
    unsigned int ui_pack_len = 0;
    FilterCommand *p_st_filter_cmd = NULL;
    Filter *p_filter_tmp = NULL;
    
    command__init(&st_command);
    
    //初始化filter信息
    if (__filter_init(&st_command, &p_st_filter_cmd, &p_filter_tmp) != FR_SUCC)
        return FR_FAIL;
    
    p_st_filter_cmd->action = "clear";
    if (__protobuf_do_pack(&st_command, &p_packed, &ui_pack_len) != FR_SUCC)
        goto err;
    
    //和服务端通信，并接收服务端返回的信息
    if (frcmd_talking(p_packed, ui_pack_len) != FR_SUCC)
        goto err;
    
    if (p_filter_tmp)
        frfree(p_filter_tmp);
    if (p_st_filter_cmd)
        frfree(p_st_filter_cmd);
    if (p_packed)
        frfree(p_packed);
    
    return FR_SUCC;
err:
    if (p_filter_tmp)
        frfree(p_filter_tmp);
    if (p_st_filter_cmd)
        frfree(p_st_filter_cmd);
    if (p_packed)
        frfree(p_packed);
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  提交/回滚 的命令
*              -c “commit cmd”
*  ARGS     :  i_action       提交/回滚
*           ： i_type         模块名
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
int frcmd_commit(int i_action, int i_type)
{
    Command st_command;
    char *p_packed = NULL;
    unsigned int ui_pack_len = 0;
    CommitCommand *p_st_cmd = NULL;
    
    command__init(&st_command);
    
    p_st_cmd = frmalloc(sizeof(CommitCommand));
    if (p_st_cmd == NULL)
        return FR_FAIL;
    
    commit_command__init(p_st_cmd);
    
    if (i_action == CMD_ACTION_COMMIT)
        p_st_cmd->action = COMMIT_COMMAND__ACTION__Commit;
    else if (i_action == CMD_ACTION_ROLLBACK)
        p_st_cmd->action = COMMIT_COMMAND__ACTION__Rollback;
    else
        goto err;
    
    if (i_type == OBJECT_L7)
        p_st_cmd->cmd = COMMIT_COMMAND__TYPE__L7;
    else if (i_type == OBJECT_L7_DEFAULT)
        p_st_cmd->cmd = COMMIT_COMMAND__TYPE__L7_DEFAULT;
    else if (i_type == OBJECT_FILTER)
        p_st_cmd->cmd = COMMIT_COMMAND__TYPE__FILTER;
    else if (i_type == OBJECT_JAVA)
        p_st_cmd->cmd = COMMIT_COMMAND__TYPE__JAVA;
    else
        goto err;

    st_command.cmd_type = COMMAND__COMMAND_TYPE__Type_CommitCommand;
    st_command.commit_cmd = p_st_cmd;
    if (__protobuf_do_pack(&st_command, &p_packed, &ui_pack_len) != FR_SUCC)
        goto err;
    
    //和服务端通信，并接收服务端返回的信息
    if (frcmd_talking(p_packed, ui_pack_len) != FR_SUCC)
        goto err;
    
    if (p_st_cmd)
        frfree(p_st_cmd);
    if (p_packed)
        frfree(p_packed);
    
    return FR_SUCC;
err:
    if (p_st_cmd)
        frfree(p_st_cmd);
    if (p_packed)
        frfree(p_packed);
    return FR_FAIL;
}

/* l7 操作 */
FR_STATIC int __l7_add(char *ip_proto, char *ip_addr, char *port, char *l7_proto)
{
	Command *p_st_cmd = NULL;
	L7Command *l7_cmd = NULL;
	L7Setting *l7_settings = NULL;
	char *p_cmd = NULL;
	unsigned int i_cmd_len = 0;
	//printf("l7_add %s %s %d %s\n", ip_proto, ip_addr, port, l7_proto);

	l7_settings = frmalloc(sizeof(L7Setting));
	if(!l7_settings)
	    goto err;

	//设置l7_settings
	l7_setting__init(l7_settings);
    l7_settings->has_ip_proto = 1;
    if(ip_proto)
        l7_settings->ip_proto = FR_L4STR2PROTO(ip_proto);
    else
        l7_settings->ip_proto = 0;
    l7_settings->has_ip = 1;
    l7_settings->ip = iptools_parse_ipaddr(ip_addr);
    l7_settings->port = port;
    l7_settings->l7_proto = l7_proto;

    l7_cmd = frmalloc(sizeof(L7Command));
    if(!l7_settings)
        goto err;
    //设置l7_cmd
    l7_command__init(l7_cmd);
    l7_cmd->action = frmalloc(strlen("add") + 1);
    if(!l7_cmd->action)
        goto err;
    snprintf(l7_cmd->action,strlen("add") + 1,"%s","add");
    l7_cmd->n_l7_settings = 1;
    l7_cmd->l7_settings = &l7_settings;

    p_st_cmd = frmalloc(sizeof(Command));
    if(!p_st_cmd)
        goto err;
    //设置p_st_cmd
    command__init(p_st_cmd);
    p_st_cmd->l7_cmd = l7_cmd;
    p_st_cmd->cmd_type = COMMAND__COMMAND_TYPE__Type_L7Command;

    //通过protobuf转化成字符串
    if(__protobuf_do_pack(p_st_cmd,&p_cmd,&i_cmd_len) != FR_SUCC)
        goto err;

    //和服务端通信，并接收服务端返回的信息
    if (frcmd_talking(p_cmd, i_cmd_len) != FR_SUCC)
        goto err;

    if(p_cmd)
        frfree(p_cmd);
    if(l7_settings)
        frfree(l7_settings);
    if(l7_cmd)
    {
        if(l7_cmd->action)
            frfree(l7_cmd->action);
        frfree(l7_cmd);
    }
    if(p_st_cmd)
        frfree(p_st_cmd);
	return FR_SUCC;

err:
    if(p_cmd)
        frfree(p_cmd);
    if(l7_settings)
        frfree(l7_settings);
    if(l7_cmd)
    {
        if(l7_cmd->action)
            frfree(l7_cmd->action);
        frfree(l7_cmd);
    }
    if(p_st_cmd)
        frfree(p_st_cmd);
	return FR_FAIL;
}

FR_STATIC int __l7_del(char *ip_proto, char *ip_addr, char *port)
{
	Command *p_st_cmd = NULL;
	L7Command *l7_cmd = NULL;
	L7Setting *l7_settings = NULL;
	char *p_cmd = NULL;
	unsigned int i_cmd_len = 0;
	//printf("l7_add %s %s %d %s\n", ip_proto, ip_addr, port, l7_proto);

	l7_settings = frmalloc(sizeof(L7Setting));
	if(!l7_settings)
	    goto err;

	//设置l7_settings
	l7_setting__init(l7_settings);
    l7_settings->has_ip_proto = 1;
    if(ip_proto)
        l7_settings->ip_proto = FR_L4STR2PROTO(ip_proto);
    else
        l7_settings->ip_proto = 0;
    l7_settings->has_ip = 1;
    l7_settings->ip = iptools_parse_ipaddr(ip_addr);
    l7_settings->port = port;

    l7_cmd = frmalloc(sizeof(L7Command));
    if(!l7_cmd)
        goto err;
    //设置l7_cmd
    l7_command__init(l7_cmd);
    l7_cmd->action = frmalloc(strlen("del") + 1);
    if(!l7_cmd->action)
        goto err;
    snprintf(l7_cmd->action,strlen("del") + 1,"%s","del");
    l7_cmd->n_l7_settings = 1;
    l7_cmd->l7_settings = &l7_settings;

    p_st_cmd = frmalloc(sizeof(Command));
    if(!p_st_cmd)
        goto err;
    //设置p_st_cmd
    command__init(p_st_cmd);
    p_st_cmd->l7_cmd = l7_cmd;
    p_st_cmd->cmd_type = COMMAND__COMMAND_TYPE__Type_L7Command;

    //通过protobuf转化成字符串
    if(__protobuf_do_pack(p_st_cmd,&p_cmd,&i_cmd_len) != FR_SUCC)
        goto err;

    //和服务端通信，并接收服务端返回的信息
    if (frcmd_talking(p_cmd, i_cmd_len) != FR_SUCC)
        goto err;

    if(p_cmd)
        frfree(p_cmd);
    if(l7_settings)
        frfree(l7_settings);
    if(l7_cmd)
    {
        if(l7_cmd->action)
            frfree(l7_cmd->action);
        frfree(l7_cmd);
    }
    if(p_st_cmd)
        frfree(p_st_cmd);
	return FR_SUCC;

err:
    if(p_cmd)
        frfree(p_cmd);
    if(l7_settings)
        frfree(l7_settings);
    if(l7_cmd)
    {
        if(l7_cmd->action)
            frfree(l7_cmd->action);
        frfree(l7_cmd);
    }
    if(p_st_cmd)
        frfree(p_st_cmd);
	return FR_FAIL;
}

FR_STATIC int __do_l7_clear(void)
{
    Command *p_st_cmd = NULL;
    L7Command *l7_cmd = NULL;
    char *p_packed = NULL;
    unsigned int ui_pack_len = 0;

    //设置l7_cmd
    l7_cmd = frmalloc(sizeof(L7Command));
    l7_command__init(l7_cmd);
    l7_cmd->action = frmalloc(strlen("clear") + 1);
    snprintf(l7_cmd->action,strlen("clear") + 1,"%s","clear");

    //设置p_st_cmd
    p_st_cmd = frmalloc(sizeof(Command));
    command__init(p_st_cmd);
    p_st_cmd->l7_cmd = l7_cmd;
    p_st_cmd->cmd_type = COMMAND__COMMAND_TYPE__Type_L7Command;

    //通过protobuf转化成字符串
    if(__protobuf_do_pack(p_st_cmd,&p_packed,&ui_pack_len) != FR_SUCC)
        goto err;

    //和服务端通信，并接收服务端返回的信息
    if (frcmd_talking(p_packed, ui_pack_len) != FR_SUCC)
        goto err;

    frfree(p_packed);
    frfree(l7_cmd->action);
    frfree(l7_cmd);
    frfree(p_st_cmd);

    return FR_SUCC;

err:
    if(l7_cmd)
    {
        if(l7_cmd->action)
            frfree(l7_cmd->action);
        frfree(l7_cmd);
    }
    if(p_st_cmd)
        frfree(p_st_cmd);
    if(p_packed)
        frfree(p_packed);

    return FR_FAIL;
}

FR_STATIC int __l7_default_add(char *ip_proto, char *l7_proto)
{
	Command *p_st_cmd = NULL;
    L7Default *l7_default = NULL;
	L7Setting *l7_settings = NULL;
	char *p_cmd = NULL;
	unsigned int i_cmd_len = 0;

	l7_settings = frmalloc(sizeof(L7Setting));
	if(!l7_settings)
	    goto err;

	//设置l7_settings
	l7_setting__init(l7_settings);
    l7_settings->has_ip_proto = 1;
    if(ip_proto)
        l7_settings->ip_proto = FR_L4STR2PROTO(ip_proto);
    else
        l7_settings->ip_proto = 0;
    l7_settings->l7_proto = l7_proto;

    l7_default = frmalloc(sizeof(L7Command));
    if(!l7_default)
        goto err;
    //设置l7_cmd
    l7_default__init(l7_default);
    l7_default->action = frmalloc(strlen("add") + 1);
    if(!l7_default->action)
        goto err;
    snprintf(l7_default->action,strlen("add") + 1,"%s","add");
    l7_default->n_l7_settings = 1;
    l7_default->l7_settings = &l7_settings;

    p_st_cmd = frmalloc(sizeof(Command));
    if(!p_st_cmd)
        goto err;
    //设置p_st_cmd
    command__init(p_st_cmd);
    p_st_cmd->l7_default = l7_default;
    p_st_cmd->cmd_type = COMMAND__COMMAND_TYPE__Type_L7Default;

    //通过protobuf转化成字符串
    if(__protobuf_do_pack(p_st_cmd,&p_cmd,&i_cmd_len) != FR_SUCC)
        goto err;

    //和服务端通信，并接收服务端返回的信息
    if (frcmd_talking(p_cmd, i_cmd_len) != FR_SUCC)
        goto err;

    if(l7_settings)
        frfree(l7_settings);
    if(l7_default)
    {
        if(l7_default->action)
            frfree(l7_default->action);
        frfree(l7_default);
    }
    if(p_st_cmd)
        frfree(p_st_cmd);
    if(p_cmd)
        frfree(p_cmd);
	return FR_SUCC;

err:
    if(l7_settings)
        frfree(l7_settings);
    if(l7_default)
    {
        if(l7_default->action)
            frfree(l7_default->action);
        frfree(l7_default);
    }
    if(p_st_cmd)
        frfree(p_st_cmd);
    if(p_cmd)
        frfree(p_cmd);
	return FR_FAIL;
}


FR_STATIC int __l7_default_del(char *ip_proto)
{
	Command *p_st_cmd = NULL;
    L7Default *l7_default = NULL;
	L7Setting *l7_settings = NULL;
	char *p_cmd = NULL;
	unsigned int i_cmd_len = 0;

	l7_settings = frmalloc(sizeof(L7Setting));
	if(!l7_settings)
	    goto err;

	//设置l7_settings
	l7_setting__init(l7_settings);
    l7_settings->has_ip_proto = 1;
    if(ip_proto)
        l7_settings->ip_proto = FR_L4STR2PROTO(ip_proto);
    else
        l7_settings->ip_proto = 0;

    l7_default = frmalloc(sizeof(L7Command));
    if(!l7_default)
        goto err;
    //设置l7_cmd
    l7_default__init(l7_default);
    l7_default->action = frmalloc(strlen("del") + 1);
    if(!l7_default->action)
        goto err;
    snprintf(l7_default->action,strlen("del") + 1,"%s","del");
    l7_default->n_l7_settings = 1;
    l7_default->l7_settings = &l7_settings;

    p_st_cmd = frmalloc(sizeof(Command));
    if(!p_st_cmd)
        goto err;
    //设置p_st_cmd
    command__init(p_st_cmd);
    p_st_cmd->l7_default = l7_default;
    p_st_cmd->cmd_type = COMMAND__COMMAND_TYPE__Type_L7Default;

    //通过protobuf转化成字符串
    if(__protobuf_do_pack(p_st_cmd,&p_cmd,&i_cmd_len) != FR_SUCC)
        goto err;

    //和服务端通信，并接收服务端返回的信息
    if (frcmd_talking(p_cmd, i_cmd_len) != FR_SUCC)
        goto err;

    if(l7_settings)
        frfree(l7_settings);
    if(l7_default)
    {
        if(l7_default->action)
            frfree(l7_default->action);
        frfree(l7_default);
    }
    if(p_st_cmd)
        frfree(p_st_cmd);
    if(p_cmd)
        frfree(p_cmd);

	return FR_SUCC;

err:
    if(l7_settings)
        frfree(l7_settings);
    if(l7_default)
    {
        if(l7_default->action)
            frfree(l7_default->action);
        frfree(l7_default);
    }
    if(p_st_cmd)
        frfree(p_st_cmd);
    if(p_cmd)
        frfree(p_cmd);
	return FR_FAIL;
}


FR_STATIC int __l7_default_clear(void)
{
	Command *p_st_cmd = NULL;
    L7Default *l7_default = NULL;
	char *p_cmd = NULL;
	unsigned int i_cmd_len = 0;

    l7_default = frmalloc(sizeof(L7Command));
    if(!l7_default)
        goto err;
    //设置l7_cmd
    l7_default__init(l7_default);
    l7_default->action = frmalloc(strlen("clear") + 1);
    if(!l7_default->action)
        goto err;
    snprintf(l7_default->action,strlen("clear") + 1,"%s","clear");

    p_st_cmd = frmalloc(sizeof(Command));
    if(!p_st_cmd)
        goto err;
    //设置p_st_cmd
    command__init(p_st_cmd);
    p_st_cmd->l7_default = l7_default;
    p_st_cmd->cmd_type = COMMAND__COMMAND_TYPE__Type_L7Default;

    //通过protobuf转化成字符串
    if(__protobuf_do_pack(p_st_cmd,&p_cmd,&i_cmd_len) != FR_SUCC)
        goto err;

    //和服务端通信，并接收服务端返回的信息
    if (frcmd_talking(p_cmd, i_cmd_len) != FR_SUCC)
        goto err;

    if(l7_default)
    {
        if(l7_default->action)
            frfree(l7_default->action);
        frfree(l7_default);
    }
    if(p_st_cmd)
        frfree(p_st_cmd);
    if(p_cmd)
        frfree(p_cmd);

	return FR_SUCC;

err:
    if(l7_default)
    {
        if(l7_default->action)
            frfree(l7_default->action);
        frfree(l7_default);
    }
    if(p_st_cmd)
        frfree(p_st_cmd);
    if(p_cmd)
        frfree(p_cmd);
	return FR_FAIL;
}

int frcmd_l7_cmd(char *p_action, char *ip_proto, char *ip_addr, char *port, char *l7_proto)
{
    int i_ret = 0;
    if(strcasecmp(p_action,"add") == 0)
    {
        i_ret = __l7_add(ip_proto, ip_addr, port, l7_proto);
        return i_ret;
    }
    if(strcasecmp(p_action,"del") == 0)
    {
        i_ret = __l7_del(ip_proto, ip_addr, port);
        return i_ret;
    }
    if(strcasecmp(p_action,"clear") == 0)
    {
        i_ret = __do_l7_clear();
        return i_ret;
    }

    return FR_FAIL;
}

int frcmd_l7_default(char *p_action, char *ip_proto, char *l7_proto)
{
    int i_ret = 0;
    if(strcasecmp(p_action,"add") == 0)
    {
        i_ret = __l7_default_add(ip_proto, l7_proto);
        return i_ret;
    }
    else if(strcasecmp(p_action,"del") == 0)
    {
        i_ret = __l7_default_del(ip_proto);
        return i_ret;
    }
    else if(strcasecmp(p_action,"clear") == 0)
    {
        i_ret = __l7_default_clear();
        return i_ret;
    }
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  打印ct 的命令
*              -c “print ct [L7_protocol]”
*  ARGS     :  p_l7_proto      ct模块名
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
int frcmd_print_ct(char *p_l7_proto)
{
    Command st_command;
    char *p_packed = NULL;
    unsigned int ui_pack_len = 0;
    PrintCommand *p_st_print = NULL;
    char **p_args = NULL;

    command__init(&st_command);

    p_st_print = frmalloc(sizeof(PrintCommand));
    if (p_st_print == NULL)
        return FR_FAIL;

    print_command__init(p_st_print);

    p_st_print->cmd = "ct";
    if(!p_l7_proto)
        p_st_print->n_args = 0;
    else
    {
        p_st_print->n_args = 1;
        p_args = frmalloc(sizeof(char *));
        if(!p_args)
            goto err;
        p_args[0] = p_l7_proto;
        p_st_print->args = p_args;
    }
    st_command.print_cmd = p_st_print;
    st_command.cmd_type = COMMAND__COMMAND_TYPE__Type_PrintCommand;

    if (__protobuf_do_pack(&st_command, &p_packed, &ui_pack_len) != FR_SUCC)
        goto err;

    //和服务端通信，并接收服务端返回的信息
    if (frcmd_talking(p_packed, ui_pack_len) != FR_SUCC)
        goto err;

    if (p_st_print)
        frfree(p_st_print);
    if (p_packed)
        frfree(p_packed);
    return FR_SUCC;
err:
    if (p_st_print)
        frfree(p_st_print);
    if (p_packed)
        frfree(p_packed);
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  打印ct 的命令
*              -c “print module [p_name]”
*  ARGS     :  p_name           module模块名(config/stat)
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
int frcmd_print_module(char *p_name)
{
    Command st_command;
    char *p_packed = NULL;
    unsigned int ui_pack_len = 0;
    PrintCommand *p_st_print = NULL;
    char **p_args = NULL;

    if(strcasecmp(p_name,"config") != 0 && strcasecmp(p_name,"stat") != 0)
        return FR_FAIL;

    command__init(&st_command);

    p_st_print = frmalloc(sizeof(PrintCommand));
    if (p_st_print == NULL)
        return FR_FAIL;

    print_command__init(p_st_print);

    p_st_print->cmd = "module";
    if(!p_name)
        p_st_print->n_args = 0;
    else
    {
        p_st_print->n_args = 1;
        p_args = frmalloc(sizeof(char *));
        if(!p_args)
            goto err;
        p_args[0] = p_name;
        p_st_print->args = p_args;
    }
    st_command.print_cmd = p_st_print;
    st_command.cmd_type = COMMAND__COMMAND_TYPE__Type_PrintCommand;

    if (__protobuf_do_pack(&st_command, &p_packed, &ui_pack_len) != FR_SUCC)
        goto err;

    //和服务端通信，并接收服务端返回的信息
    if (frcmd_talking(p_packed, ui_pack_len) != FR_SUCC)
        goto err;

    if (p_st_print)
        frfree(p_st_print);
    if (p_packed)
        frfree(p_packed);
    return FR_SUCC;
err:
    if (p_st_print)
        frfree(p_st_print);
    if (p_packed)
        frfree(p_packed);
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  打印系统参数 的命令
*              -c “print p_name”
*  ARGS     :  p_name   (system/module/topology/thread/server/filter/l7_default
*                           /java/memory/)
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
int frcmd_client_print(const char *p_name)
{
    Command st_command;
    char *p_packed = NULL;
    unsigned int ui_pack_len = 0;
    PrintCommand *p_st_print = NULL;

    command__init(&st_command);

    p_st_print = frmalloc(sizeof(PrintCommand));
    if (p_st_print == NULL)
        return FR_FAIL;

    print_command__init(p_st_print);
    if(strncasecmp(p_name,"system",strlen(p_name)) == 0)
        p_st_print->cmd = "system";
    else if(strncasecmp(p_name,"topology",strlen(p_name)) == 0)
        p_st_print->cmd = "topology";
    else if(strncasecmp(p_name,"thread",strlen(p_name)) == 0)
        p_st_print->cmd = "thread";
    else if(strncasecmp(p_name,"server",strlen(p_name)) == 0)
        p_st_print->cmd = "server";
    else if(strncasecmp(p_name,"filter",strlen(p_name)) == 0)
        p_st_print->cmd = "filter";
    else if(strncasecmp(p_name,"l7_default",strlen(p_name)) == 0)
        p_st_print->cmd = "l7_default";
    else if(strncasecmp(p_name,"java",strlen(p_name)) == 0)
        p_st_print->cmd = "java";
    else if(strncasecmp(p_name,"memory",strlen(p_name)) == 0)
        p_st_print->cmd = "memory";
    else
        return FR_FAIL;

    p_st_print->n_args = 0;
    st_command.print_cmd = p_st_print;
    st_command.cmd_type = COMMAND__COMMAND_TYPE__Type_PrintCommand;

    if (__protobuf_do_pack(&st_command, &p_packed, &ui_pack_len) != FR_SUCC)
        goto err;

    //和服务端通信，并接收服务端返回的信息
    if (frcmd_talking(p_packed, ui_pack_len) != FR_SUCC)
        goto err;

    if (p_st_print)
        frfree(p_st_print);
    if (p_packed)
        frfree(p_packed);
    return FR_SUCC;
err:
    if (p_st_print)
        frfree(p_st_print);
    if (p_packed)
        frfree(p_packed);
    return FR_FAIL;
}


/*******************************************************************************
*  FUNC     :  退出 命令
*              -c “exit”
*  ARGS     :
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
int frcmd_exit(void)
{
    Command st_command;
    char *p_packed = NULL;
    unsigned int ui_pack_len = 0;
    
    command__init(&st_command);
    
    st_command.cmd_type = COMMAND__COMMAND_TYPE__Type_ExitCommand;
    
    if (__protobuf_do_pack(&st_command, &p_packed, &ui_pack_len) != FR_SUCC)
        goto err;
    
    //和服务端通信，并接收服务端返回的信息
    if (frcmd_talking(p_packed, ui_pack_len) != FR_SUCC)
        goto err;

    if (p_packed)
        frfree(p_packed);
    return FR_SUCC;
err:
    if (p_packed)
        frfree(p_packed);
    return FR_FAIL;
}


/*******************************************************************************
*  FUNC     :  退出 命令
*              -c “exit”
*  ARGS     :
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __module_add(char *p_path,char *l4_proto, int l7_proto, char *p_l7_proto_name,int mem_size)
{
    Command *p_st_cmd = NULL;
    ModuleCommand *p_module_cmd = NULL;
    char *p_action = NULL;
    char *p_packed = NULL;
    unsigned int ui_pack_len = 0;


    p_action = frmalloc(strlen("add") + 1);
    if(!p_action)
        goto err;
    snprintf(p_action,strlen("add") + 1,"%s","add");

    p_module_cmd = frmalloc(sizeof(ModuleCommand));
    if(!p_module_cmd)
        goto err;

    module_command__init(p_module_cmd);
    p_module_cmd->action = p_action;
    p_module_cmd->so_path = p_path;
    p_module_cmd->l7_proto = l7_proto;
    if(l4_proto)
        p_module_cmd->l4_proto = FR_L4STR2PROTO(l4_proto);
    else
        p_module_cmd->l4_proto = 0;
    p_module_cmd->l7_protoname = p_l7_proto_name;

    p_module_cmd->mem_size = mem_size;

    p_st_cmd = frmalloc(sizeof(Command));
    if(!p_st_cmd)
        goto err;
    //设置p_st_cmd
    command__init(p_st_cmd);
    p_st_cmd->cmd_type = COMMAND__COMMAND_TYPE__Type_ModuleCommand;
    p_st_cmd->module_cmd = p_module_cmd;

    //通过protobuf转化成字符串
    if(__protobuf_do_pack(p_st_cmd,&p_packed,&ui_pack_len) != FR_SUCC)
        goto err;

    //和服务端通信，并接收服务端返回的信息
    if (frcmd_talking(p_packed, ui_pack_len) != FR_SUCC)
        goto err;

    frfree(p_module_cmd->action);
    frfree(p_module_cmd);
    frfree(p_st_cmd);
    frfree(p_packed);
    return FR_SUCC;

err:
    if(p_action)
        frfree(p_action);
    if(p_module_cmd)
        frfree(p_module_cmd);
    if(p_st_cmd)
        frfree(p_st_cmd);
    if(p_packed)
        frfree(p_packed);
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  退出 命令
*              -c “exit”
*  ARGS     :
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __module_del(int l7_proto)
{
    Command *p_st_cmd = NULL;
    ModuleCommand *p_module_cmd = NULL;
    char *p_action = NULL;
    char *p_packed = NULL;
    unsigned int ui_pack_len = 0;


    p_action = frmalloc(strlen("del") + 1);
    if(!p_action)
        goto err;
    snprintf(p_action,strlen("del") + 1,"%s","del");
    p_module_cmd = frmalloc(sizeof(ModuleCommand));
    if(!p_module_cmd)
        goto err;

    module_command__init(p_module_cmd);
    p_module_cmd->action = p_action;
    p_module_cmd->l7_proto = l7_proto;

    p_st_cmd = frmalloc(sizeof(Command));
    if(!p_st_cmd)
        goto err;
    //设置p_st_cmd
    command__init(p_st_cmd);
    p_st_cmd->cmd_type = COMMAND__COMMAND_TYPE__Type_ModuleCommand;
    p_st_cmd->module_cmd = p_module_cmd;

    //通过protobuf转化成字符串
    if(__protobuf_do_pack(p_st_cmd,&p_packed,&ui_pack_len) != FR_SUCC)
        goto err;

    //和服务端通信，并接收服务端返回的信息
    if (frcmd_talking(p_packed, ui_pack_len) != FR_SUCC)
        goto err;

    frfree(p_module_cmd->action);
    frfree(p_module_cmd);
    frfree(p_st_cmd);
    return FR_SUCC;

err:
    if(p_action)
        frfree(p_action);
    if(p_module_cmd)
        frfree(p_module_cmd);
    if(p_st_cmd)
        frfree(p_st_cmd);
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  退出 命令
*              -c “exit”
*  ARGS     :
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __module_clear(void)
{
    Command *p_st_cmd = NULL;
    ModuleCommand *p_module_cmd = NULL;
    char *p_action = NULL;
    char *p_packed = NULL;
    unsigned int ui_pack_len = 0;


    p_action = frmalloc(strlen("clear") + 1);
    if(!p_action)
        goto err;
    snprintf(p_action,strlen("clear") + 1,"%s","clear");
    p_module_cmd = frmalloc(sizeof(ModuleCommand));
    if(!p_module_cmd)
        goto err;

    module_command__init(p_module_cmd);
    p_module_cmd->action = p_action;

    p_st_cmd = frmalloc(sizeof(Command));
    if(!p_st_cmd)
        goto err;
    //设置p_st_cmd
    command__init(p_st_cmd);
    p_st_cmd->cmd_type = COMMAND__COMMAND_TYPE__Type_ModuleCommand;
    p_st_cmd->module_cmd = p_module_cmd;

    //通过protobuf转化成字符串
    if(__protobuf_do_pack(p_st_cmd,&p_packed,&ui_pack_len) != FR_SUCC)
        goto err;

    //和服务端通信，并接收服务端返回的信息
    if (frcmd_talking(p_packed, ui_pack_len) != FR_SUCC)
        goto err;

    frfree(p_module_cmd->action);
    frfree(p_module_cmd);
    frfree(p_st_cmd);
    return FR_SUCC;

err:
    if(p_action)
        frfree(p_action);
    if(p_module_cmd)
        frfree(p_module_cmd);
    if(p_st_cmd)
        frfree(p_st_cmd);
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  退出 命令
*              -c “exit”
*  ARGS     :
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
int do_module_cmd(char *p_action,char *p_path,char *l4_proto, int l7_proto, char *p_l7_proto_name,int i_mem_size)
{
    int i_ret = 0;
    if(strncasecmp(p_action,"add",strlen("add")) == 0)
        i_ret = __module_add(p_path,l4_proto,l7_proto,p_l7_proto_name,i_mem_size);
    else if(strncasecmp(p_action,"del",strlen("del")) == 0)
        i_ret = __module_del(l7_proto);
    else if(strncasecmp(p_action,"clear",strlen("clear")) == 0)
        i_ret = __module_clear();
    else
        return FR_FAIL;

    return i_ret;
}

